package main

import (
	"context"
	"fmt"
	"reflect"
	"sync"
	"time"
)

// ==========================================
// 泛型（Go 1.18+）
// ==========================================

// 定义泛型类型约束
type Number interface {
	~int | ~int32 | ~int64 | ~float32 | ~float64
}

// 泛型函数：计算切片的和
func Sum[T Number](numbers []T) T {
	var sum T
	for _, num := range numbers {
		sum += num
	}
	return sum
}

// 泛型函数：查找最大值
func Max[T Number](a, b T) T {
	if a > b {
		return a
	}
	return b
}

// 泛型类型：栈
type Stack[T any] struct {
	items []T
}

func (s *Stack[T]) Push(item T) {
	s.items = append(s.items, item)
}

func (s *Stack[T]) Pop() (T, bool) {
	var zero T
	if len(s.items) == 0 {
		return zero, false
	}
	item := s.items[len(s.items)-1]
	s.items = s.items[:len(s.items)-1]
	return item, true
}

// ==========================================
// 反射
// ==========================================

// 使用反射的结构体
type Person struct {
	Name    string `json:"name" validate:"required"`
	Age     int    `json:"age" validate:"gte=0,lte=150"`
	Address string `json:"address"`
}

// 使用反射打印结构体字段
func inspectStruct(v interface{}) {
	// 获取值的反射类型对象
	t := reflect.TypeOf(v)

	// 如果是指针，获取其实际指向的类型
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	// 确保是结构体
	if t.Kind() != reflect.Struct {
		fmt.Println("不是结构体")
		return
	}

	fmt.Printf("\n结构体 %s 的字段:\n", t.Name())
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fmt.Printf("字段名: %-10s 类型: %-10s", field.Name, field.Type)
		if tag := field.Tag.Get("json"); tag != "" {
			fmt.Printf(" JSON标签: %-10s", tag)
		}
		if tag := field.Tag.Get("validate"); tag != "" {
			fmt.Printf(" 验证规则: %-10s", tag)
		}
		fmt.Println()
	}
}

// 使用反射设置结构体字段值
func setField(v interface{}, name string, value interface{}) error {
	rv := reflect.ValueOf(v)
	if rv.Kind() != reflect.Ptr || rv.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("需要结构体指针")
	}

	// 获取结构体的值
	rv = rv.Elem()

	// 获取字段
	fv := rv.FieldByName(name)
	if !fv.IsValid() {
		return fmt.Errorf("没有名为 %s 的字段", name)
	}

	// 检查字段是否可设置
	if !fv.CanSet() {
		return fmt.Errorf("字段 %s 不可设置", name)
	}

	// 设置字段值
	fv.Set(reflect.ValueOf(value))
	return nil
}

// ==========================================
// Context包的使用
// ==========================================

// 模拟耗时操作
func longRunningOperation1(ctx context.Context) error {
	// 创建一个通道用于发送结果
	done := make(chan error, 1)

	go func() {
		// 模拟耗时操作
		time.Sleep(2 * time.Second)
		done <- nil
	}()

	// 等待操作完成或上下文取消
	select {
	case err := <-done:
		return err
	case <-ctx.Done():
		return ctx.Err()
	}
}

// 带有上下文的操作链
func operationChain(ctx context.Context) error {
	// 第一个操作
	if err := operation1(ctx); err != nil {
		return err
	}

	// 第二个操作
	if err := operation2(ctx); err != nil {
		return err
	}

	return nil
}

func operation1(ctx context.Context) error {
	select {
	case <-time.After(1 * time.Second):
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}

func operation2(ctx context.Context) error {
	select {
	case <-time.After(1 * time.Second):
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}

// ==========================================
// 互斥锁和读写锁
// ==========================================

// 使用互斥锁的计数器
type Counter struct {
	mu    sync.Mutex
	count int
}

func (c *Counter) Increment() {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.count++
}

func (c *Counter) Value() int {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.count
}

// 使用读写锁的缓存
type Cache struct {
	sync.RWMutex
	data map[string]interface{}
}

func NewCache() *Cache {
	return &Cache{
		data: make(map[string]interface{}),
	}
}

func (c *Cache) Set(key string, value interface{}) {
	c.Lock()
	defer c.Unlock()
	c.data[key] = value
}

func (c *Cache) Get(key string) (interface{}, bool) {
	c.RLock()
	defer c.RUnlock()
	value, ok := c.data[key]
	return value, ok
}

func main() {
	// ==========================================
	// 泛型示例
	// ==========================================

	// 使用泛型函数
	ints := []int{1, 2, 3, 4, 5}
	floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}

	fmt.Printf("整数切片的和: %d\n", Sum(ints))
	fmt.Printf("浮点数切片的和: %.2f\n", Sum(floats))

	// 使用泛型类型
	stack := &Stack[string]{}
	stack.Push("Hello")
	stack.Push("World")

	if item, ok := stack.Pop(); ok {
		fmt.Printf("弹出: %s\n", item)
	}

	// ==========================================
	// 反射示例
	// ==========================================

	// 创建Person实例
	person := Person{
		Name:    "张三",
		Age:     25,
		Address: "北京",
	}

	// 检查结构体
	inspectStruct(person)

	// 使用反射设置字段
	err := setField(&person, "Age", 26)
	if err != nil {
		fmt.Println("设置字段错误:", err)
	}
	fmt.Printf("更新后的年龄: %d\n", person.Age)

	// ==========================================
	// Context示例
	// ==========================================

	// 创建带取消的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	// 执行带有上下文的操作
	err = longRunningOperation1(ctx)
	if err != nil {
		fmt.Println("操作错误:", err)
	}

	// 执行操作链
	err = operationChain(ctx)
	if err != nil {
		fmt.Println("操作链错误:", err)
	}

	// ==========================================
	// 互斥锁示例
	// ==========================================

	// 使用计数器
	counter := &Counter{}
	var wg sync.WaitGroup

	// 并发增加计数
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			counter.Increment()
		}()
	}

	wg.Wait()
	fmt.Printf("计数器最终值: %d\n", counter.Value())

	// ==========================================
	// 读写锁示例
	// ==========================================

	// 创建缓存
	cache := NewCache()

	// 并发写入和读取
	wg.Add(2)

	// 写入goroutine
	go func() {
		defer wg.Done()
		for i := 0; i < 5; i++ {
			key := fmt.Sprintf("key%d", i)
			cache.Set(key, i)
			time.Sleep(100 * time.Millisecond)
		}
	}()

	// 读取goroutine
	go func() {
		defer wg.Done()
		for i := 0; i < 10; i++ {
			key := fmt.Sprintf("key%d", i%5)
			if value, ok := cache.Get(key); ok {
				fmt.Printf("读取 %s: %v\n", key, value)
			}
			time.Sleep(50 * time.Millisecond)
		}
	}()

	wg.Wait()

	// ==========================================
	// 练习
	// ==========================================

	// 1. 创建一个泛型函数，实现对任意类型切片的过滤

	// 2. 使用反射实现一个简单的JSON序列化器

	// 3. 实现一个带有超时和取消功能的工作池

	// 4. 创建一个线程安全的LRU缓存

	// 5. 使用context实现一个带有超时的HTTP客户端
}

// ==========================================
// 练习参考实现
// ==========================================

// 1. 泛型过滤函数
func Filter[T any](slice []T, f func(T) bool) []T {
	var result []T
	for _, v := range slice {
		if f(v) {
			result = append(result, v)
		}
	}
	return result
}

// 2. 简单的JSON序列化器
func toJSON(v interface{}) (string, error) {
	val := reflect.ValueOf(v)
	switch val.Kind() {
	case reflect.Struct:
		return structToJSON(val)
	case reflect.Map:
		return mapToJSON(val)
	default:
		return "", fmt.Errorf("不支持的类型: %v", val.Kind())
	}
}

func structToJSON(val reflect.Value) (string, error) {
	// 实现省略
	return "", nil
}

func mapToJSON(val reflect.Value) (string, error) {
	// 实现省略
	return "", nil
}

// 3. 带超时的工作池
type WorkPool struct {
	workers int
	tasks   chan func() error
}

func NewWorkPool(workers int) *WorkPool {
	return &WorkPool{
		workers: workers,
		tasks:   make(chan func() error, workers),
	}
}

func (p *WorkPool) Start(ctx context.Context) {
	for i := 0; i < p.workers; i++ {
		go func() {
			for {
				select {
				case task := <-p.tasks:
					task()
				case <-ctx.Done():
					return
				}
			}
		}()
	}
}

// 4. 线程安全的LRU缓存
type LRUCache struct {
	sync.RWMutex
	capacity int
	cache    map[string]interface{}
	order    []string
}

func NewLRUCache(capacity int) *LRUCache {
	return &LRUCache{
		capacity: capacity,
		cache:    make(map[string]interface{}),
		order:    make([]string, 0),
	}
}

func (c *LRUCache) Set(key string, value interface{}) {
	c.Lock()
	defer c.Unlock()

	// 实现省略
}

func (c *LRUCache) Get(key string) (interface{}, bool) {
	c.RLock()
	defer c.RUnlock()

	// 实现省略
	return nil, false
}

// 5. 带超时的HTTP客户端
func httpGetWithTimeout(ctx context.Context, url string) ([]byte, error) {
	// 实现省略
	return nil, nil
}
